package com.hxc.shop.utils;


import com.hxc.shop.config.EmailConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.SentDateTerm;
import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 *  邮件工具类
 *  EmailConfig为yml文件的邮件配置
 *  通过它获取yml配置的邮箱值传递进行发送、接收邮件信息
 *  在需要使用的方法通过
 *  @Resource
 *  private EmailConfig emailConfig;
 *  进行传递参数调用方法
 * */
@Component
@Configuration
public class MailUtil {
    public static  Store store;
    public static  Folder folder;

    private final Logger logger = LoggerFactory.getLogger(MailUtil.class);

    /**
     * @param emailConfig 邮箱配置
     * @param toEmail 发送邮件给xx邮箱
     * @param subject 主题
     * @param text 正文
     * @description 发送纯文本邮件
     * */
    public void sendMail(EmailConfig emailConfig,String toEmail, String subject, String text) {
        try {
            JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
            javaMailSender.setUsername(emailConfig.getUsername());
            javaMailSender.setPassword(emailConfig.getPassword());
            javaMailSender.setHost(emailConfig.getHost());
            javaMailSender.setPort(emailConfig.getPort());
            javaMailSender.setProtocol(emailConfig.getProtocol());
            javaMailSender.setDefaultEncoding(emailConfig.getDefaultEncoding());
            Properties mailProperties = new Properties();
            mailProperties.put("mail.smtp.auth", true);
            mailProperties.put("mail.smtp.starttls.enable", true);
            javaMailSender.setJavaMailProperties(mailProperties);
            MimeMessage mimeMessage = getMimeMessage(emailConfig,toEmail, subject, text, javaMailSender);
            javaMailSender.send(mimeMessage);
            logger.info("发往 " + toEmail + " 邮件【" + subject + "】 发送成功");
        } catch (MessagingException e) {
            e.printStackTrace();
            logger.error("发往 " + toEmail + " 邮件【" + subject + "】 发送异常", e);
        }
    }

    /**
     * @param emailConfig 邮箱配置
     * @param toEmail 接收邮件邮箱
     * @param subject 主题
     * @param text 正文
     * @param javaMailSender 邮箱发送服务
     * @description 最终调用本方法发送邮件
     * */
    private MimeMessage getMimeMessage(EmailConfig emailConfig,String toEmail, String subject, String text, JavaMailSenderImpl javaMailSender) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        mimeMessageHelper.setFrom(emailConfig.getUsername());
        mimeMessageHelper.setTo(toEmail.split(","));
        mimeMessageHelper.setSubject(subject);
        mimeMessageHelper.setText(text, true);
        return mimeMessage;
    }

    /**
     * @param emailConfig 邮箱配置
     * @param toEmail 接收邮件的邮箱
     * @param subject 主题
     * @param text 正文
     * @param files 附件
     * @description 发送带有附件的邮箱
     * */
    public void sendMailWithFile(EmailConfig emailConfig,String toEmail, String subject, String text, List<File> files) {
        try {
            JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
            javaMailSender.setUsername(emailConfig.getUsername());
            javaMailSender.setPassword(emailConfig.getPassword());
            javaMailSender.setHost(emailConfig.getHost());
            javaMailSender.setPort(emailConfig.getPort());
            javaMailSender.setProtocol(emailConfig.getProtocol());
            javaMailSender.setDefaultEncoding(emailConfig.getDefaultEncoding());
            Properties mailProperties = new Properties();
            mailProperties.put("mail.smtp.auth", true);
            mailProperties.put("mail.smtp.starttls.enable", true);
            javaMailSender.setJavaMailProperties(mailProperties);
            MimeMessage mimeMessage = getMimeMessage(emailConfig,toEmail, subject, text, javaMailSender, files);
            System.out.println("toEmail: " + toEmail);
            javaMailSender.send(mimeMessage);
            logger.info("发往 " + toEmail + " 邮件【" + subject + "】 发送成功");
        } catch (MessagingException e) {
            e.printStackTrace();
            logger.error("发往 " + toEmail + " 邮件【" + subject + "】 发送异常", e);
        }
    }


    /**
     * @param emailConfig 邮箱配置
     * @param toEmail 接收邮件的邮箱
     * @param subject 主题
     * @param text 正文
     * @param javaMailSender 邮件发送服务
     * @param files 附件文件
     * @description 有附件时。最终调用本方法发送邮件
     * */
    private MimeMessage getMimeMessage(EmailConfig emailConfig,String toEmail, String subject, String text, JavaMailSenderImpl javaMailSender, List<File> files) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        mimeMessageHelper.setFrom(emailConfig.getUsername());
        mimeMessageHelper.setTo(toEmail.split(","));
        mimeMessageHelper.setSubject(subject);
        mimeMessageHelper.setText(text, true);
        if(!CollectionUtils.isEmpty(files)){
            for (File file : files) {
                mimeMessageHelper.addAttachment(file.getName(), file);
            }
        }
        return mimeMessage;
    }

    /**
     * @param toEmail 发送邮件给xx邮箱
     * @param ccEmail 抄送邮件给xx邮箱
     * @param subject 邮件主题
     * @param text 邮件正文
     * @param files 邮件附件文件
     * @description 发送附带文件的邮件给xx邮箱，文件为空和不为空皆可
     * */
    public void sendMailWithFile(EmailConfig emailConfig,String toEmail, String ccEmail, String subject, String text, List<File> files) {
        try {
            String bccEmail = "";
            JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
            javaMailSender.setUsername(emailConfig.getUsername());
            javaMailSender.setPassword(emailConfig.getPassword());
            javaMailSender.setHost(emailConfig.getHost());
            javaMailSender.setPort(emailConfig.getPort());
            javaMailSender.setProtocol(emailConfig.getProtocol());
            javaMailSender.setDefaultEncoding(emailConfig.getDefaultEncoding());
            Properties mailProperties = new Properties();
            mailProperties.put("mail.smtp.auth", true);
            mailProperties.put("mail.smtp.starttls.enable", true);
            javaMailSender.setJavaMailProperties(mailProperties);
            MimeMessage mimeMessage = getMimeMessage(emailConfig,toEmail, ccEmail, bccEmail, subject, text, javaMailSender, files);
            System.out.println("toEmail: " + toEmail);
            javaMailSender.send(mimeMessage);
            logger.info("发往 " + toEmail + " 邮件【" + subject + "】 发送成功");
        } catch (MessagingException e) {
            e.printStackTrace();
            logger.error("发往 " + toEmail + " 邮件【" + subject + "】 发送异常", e);
        }
    }

    /**
     * @param emailConfig 邮箱配置
     * @param toEmail 接收邮件的邮箱
     * @param ccEmail 抄送邮件给xx邮箱
     * @param bccEmail 密码抄送邮件给xx邮箱
     * @param subject 主题
     * @param text 正文
     * @param javaMailSender 邮件发送服务
     * @param files 附件文件
     * @description 有附件时,且需要抄送和秘密抄送邮件的时候，最终调用本方法发送邮件
     * */
    private MimeMessage getMimeMessage(EmailConfig emailConfig,String toEmail, String ccEmail, String bccEmail, String subject, String text, JavaMailSenderImpl javaMailSender, List<File> files) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        mimeMessageHelper.setFrom(emailConfig.getUsername());
        mimeMessageHelper.setTo(toEmail.split(","));
        if (!"".equals(ccEmail)) {
            mimeMessageHelper.setCc(ccEmail.split(","));
        }
        if (!"".equals(bccEmail)) {
            mimeMessageHelper.setBcc(bccEmail.split(","));
        }
        mimeMessageHelper.setSubject(subject);
        mimeMessageHelper.setText(text, true);
        if(!CollectionUtils.isEmpty(files)){
            for (File file : files) {
                mimeMessageHelper.addAttachment(file.getName(), file);
            }
        }
        return mimeMessage;
    }

    /**
     * @param toEmail 发送邮件给xx邮箱
     * @param ccEmail 抄送邮件给xx邮箱
     * @param bccEmail 秘密抄送邮件给xx邮箱
     * @param subject 邮件主题
     * @param text 邮件正文
     * @description 发送纯文本邮件到xx邮箱
     * */
    public void sendMail(EmailConfig emailConfig,String toEmail, String ccEmail, String bccEmail, String subject, String text) {
        try {
            JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
            javaMailSender.setUsername(emailConfig.getUsername());
            javaMailSender.setPassword(emailConfig.getPassword());
            javaMailSender.setHost(emailConfig.getHost());
            javaMailSender.setPort(emailConfig.getPort());
            javaMailSender.setProtocol(emailConfig.getProtocol());
            javaMailSender.setDefaultEncoding(emailConfig.getDefaultEncoding());
            Properties mailProperties = new Properties();
            mailProperties.put("mail.smtp.auth", true);
            mailProperties.put("mail.smtp.starttls.enable", true);
            javaMailSender.setJavaMailProperties(mailProperties);
            MimeMessage mimeMessage = getMimeMessage(emailConfig,toEmail, ccEmail, bccEmail, subject, text, javaMailSender);
            javaMailSender.send(mimeMessage);
            logger.info("发往 " + toEmail + " 邮件【" + subject + "】 发送成功");
        } catch (MessagingException e) {
            e.printStackTrace();
            logger.error("发往 " + toEmail + " 邮件【" + subject + "】 发送异常", e);
        }
    }

    /**
     * @param emailConfig 邮箱配置
     * @param toEmail 接收邮件的邮箱
     * @param ccEmail 抄送邮件给xx邮箱
     * @param bccEmail 密码抄送邮件给xx邮箱
     * @param subject 主题
     * @param text 正文
     * @param javaMailSender 邮件发送服务
     * @description 无附件时,且需要抄送和秘密抄送邮件的时候，最终调用本方法发送邮件
     * */
    private MimeMessage getMimeMessage(EmailConfig emailConfig,String toEmail, String ccEmail, String bccEmail, String subject, String text, JavaMailSenderImpl javaMailSender) throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        mimeMessageHelper.setFrom(emailConfig.getUsername());
        mimeMessageHelper.setTo(toEmail.split(","));
        if (!"".equals(ccEmail)) {
            mimeMessageHelper.setCc(ccEmail.split(","));
        }
        if (!"".equals(bccEmail)) {
            mimeMessageHelper.setBcc(bccEmail.split(","));
        }
        mimeMessageHelper.setSubject(subject);
        mimeMessageHelper.setText(text, true);
        return mimeMessage;
    }

    /**
     * @param emailConfig 邮箱配置
     * @param days 获取xx天到现在的邮件
     * @description 接收邮件
     * */
    public  Message[] receiveMail(EmailConfig emailConfig,Integer days) throws Exception {
        Properties props = new Properties();
        props.put("mail.pop3.host", emailConfig.getReceiveHost());
        props.put("mail.pop3.port", emailConfig.getReceivePort());
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(emailConfig.getReceiveUsername(), emailConfig.getReceivePassword());
            }
        });
        store =  session.getStore(emailConfig.getReceiveProtocol());
        store.connect();
        folder = store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        Calendar calendar = Calendar.getInstance();
        // 搜索xxx天前到今天收到的的所有邮件，根据时间筛选邮件
        calendar.add(Calendar.DAY_OF_MONTH, -days);
        // 搜索5分钟前到现在收到的所有邮件
//        calendar.add(Calendar.MINUTE,-5);
        // 创建ReceivedDateTerm对象，ComparisonTerm.GE（大于等于），Date类型的时间 new Date(calendar.getTimeInMillis())----（表示1天前）
        SentDateTerm term = new SentDateTerm(ComparisonTerm.GE, new Date(calendar.getTimeInMillis()));
        Message[] messages = folder.search(term);
        return messages;
    }

    /**
     * @param emailConfig 邮箱配置
     * @param username 需要清除邮件的邮箱
     * @param password 需要清除邮件的邮箱密码
     * @param days 需要清除xx天内的邮件
     * */
    public static void clearMail(EmailConfig emailConfig,String username,String password,Integer days) throws Exception {
        Properties props = new Properties();
        props.put("mail.pop3.host", emailConfig.getReceiveHost());
        props.put("mail.pop3.port", emailConfig.getReceivePort());
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        Store store = session.getStore(emailConfig.getReceiveProtocol());
        store.connect();
        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        Calendar calendar = Calendar.getInstance();
        // 搜索xx天前收到的的所有邮件，根据时间筛选邮件
        calendar.add(Calendar.DAY_OF_MONTH, -days);
        SentDateTerm term = new SentDateTerm(ComparisonTerm.LE, new Date(calendar.getTimeInMillis()));
        Message[] messages = folder.search(term);
        for (int i = 0; i < messages.length; i++) {
//            if(!messages[i].getFolder().isOpen()) //判断是否open
//                messages[i].getFolder().open(Folder.READ_WRITE);
            messages[i].setFlag(Flags.Flag.DELETED, true);
        }
    }

}
